﻿using MediaAdmin.Application.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Net;
using System.Net.Http;
using System.IO;
using System.Diagnostics;
using System.Threading;
using MediaAdmin.Application;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
using System.Text;

namespace MediaAdmin.Controllers
{
    public partial class FileController : BaseApiController
    {

        public Task<HttpResponseMessage> Post(string container)
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            string root = HttpContext.Current.Server.MapPath("~/App_Data");
            var provider = new MultipartFormDataStreamProvider(root);
            
            var task = Request.Content.ReadAsMultipartAsync(provider).
                ContinueWith<HttpResponseMessage>(t =>
                {
                    if (t.IsFaulted || t.IsCanceled)
                    {
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
                    }
                    var model = new FileDescriptor() { FilePath = provider.FileData[0].LocalFileName };

                    if (provider.FormData.AllKeys.Where(x => x == "name").Any())
                    {
                        model.FileName = provider.FormData.GetValues("name").SingleOrDefault();
                    }
                    if (provider.FormData.AllKeys.Where(x => x == "chunk").Any())
                    {
                        model.IsChunked = true;
                        model.ChunkNum = Int32.Parse(provider.FormData.GetValues("chunk").SingleOrDefault());
                        model.ChunksTotal = Int32.Parse(provider.FormData.GetValues("chunks").SingleOrDefault());
                    }
                    
                    if(provider.FileData.Count!=1)
                        return Request.CreateResponse(HttpStatusCode.NotFound);

                    UploadViaSDK(container, model);

                    File.Delete(model.FilePath);                   

                    return Request.CreateResponse(HttpStatusCode.OK);
                });

            return task;
        }


        private void UploadViaSDK(string container, FileDescriptor file)
        {
            var acc = CloudStorageAccount.Parse(Config.StorageSettings.StorageConnectionString);
            CloudBlobClient blobClient = acc.CreateCloudBlobClient();
            CloudBlobContainer bcontainer = blobClient.GetContainerReference(container);
            var blockblob = bcontainer.GetBlockBlobReference(file.FileName);
            using(var stream = File.OpenRead(file.FilePath))
            {
                blockblob.PutBlock(NumToBlockid(file.ChunkNum), stream, null );
            }

            if (file.IsChunked && (file.ChunkNum + 1 == file.ChunksTotal))
            {
                string[] ids = new string[file.ChunksTotal];
                for (var iter = 0; iter < ids.Length; iter++)
                    ids[iter] = NumToBlockid(iter);
                blockblob.PutBlockList(ids);
            }
        }

        private string NumToBlockid(int num)
        {
            StringBuilder sb = new StringBuilder();
            var nums = num.ToString();

            for (int iter = 4; iter >= 0; iter--)
            {
                int index = 4 - iter;

                sb.Append( index < nums.Length ? nums[nums.Length - 1 - index] : '0');
            }

            return Convert.ToBase64String(Encoding.UTF8.GetBytes(sb.ToString()));
        }
    }
}
